﻿using SmartWMS.Common.Extensions;
using SmartWMS.Common.ResponseOutput;
using SmartWMS.Domain.Base;
using SmartWMS.Domain.BasicsDatum;
using SmartWMS.Domain.BusinessManage;
using SmartWMS.Domain.StatementManage;
using SmartWMS.Domain.WarehouseManage;
using SmartWMS.EntityFramework;
using SmartWMS.Server.Repository;
using SmartWMS.Server.WarehouseManage.StockManagement.Dto;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SmartWMS.Server.WarehouseManage.StockManagement
{
	public class StockServe : IStockServe
	{
		private readonly SmartWMSContext _smartWMSContext;

		//入库表
		private IRepository<InWarehouse> _inWarehouse;
		//入库明细表
		private IRepository<InWarehouseDetail> _inWarehouseDetail;
		//仓库表
		private IRepository<Warehouse> _warehouse;
		//产品表
		private IRepository<Product> _product;
		//单位表
		private IRepository<Unit> _unit;
		//库存清单
		private IRepository<Location> _location;
		//采购表
		private IRepository<ProcureManagement> _procureManagement;
		//库存表
		private IRepository<Inventory> _inventory;


		/// <summary>
		/// 构造函数
		/// </summary>
		/// <param name="inWarehouse"></param>
		/// <param name="inWarehouseDetail"></param>
		/// <param name="warehouse"></param>
		/// <param name="product"></param>
		/// <param name="unit"></param>
		public StockServe(IRepository<InWarehouse> inWarehouse, IRepository<InWarehouseDetail> inWarehouseDetail, IRepository<Warehouse> warehouse, IRepository<Product> product, IRepository<Unit> unit, IRepository<Location> location, IRepository<ProcureManagement> procureManagement, SmartWMSContext smartWMSContext, IRepository<Inventory> inventory)
		{
			_smartWMSContext = smartWMSContext;
			_inWarehouse = inWarehouse;
			_inWarehouseDetail = inWarehouseDetail;
			_warehouse = warehouse;
			_product = product;
			_unit = unit;
			_location = location;
			_procureManagement = procureManagement;
			_inventory = inventory;
		}

		/// <summary>
		/// 显示入库管理(分页)
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		/// <exception cref="NotImplementedException"></exception>
		public async Task<Response<List<StockDto>>> GetStockList(StockSelectDto input)
		{
			try
			{
				var InWarehouse = await _inWarehouse.GetAllListAsync();
				var InWarehouseDetail = await _inWarehouseDetail.GetAllListAsync();
				var Warehouse = await _warehouse.GetAllListAsync();
				var Product = await _product.GetAllListAsync();
				var Unit = await _unit.GetAllListAsync();
				var Location = await _location.GetAllListAsync();

				//六表联查
				var list = (from i in InWarehouseDetail
							join iw in InWarehouse
							on i.InWarehouseCode equals iw.WarehousingCode
							join p in Product
							on i.ProductCode equals p.ProductCode
							join w in Warehouse
							on p.DefaultWarehouseId equals w.Id
							join it in Location
							on w.Id equals it.WarehouseId
							select new StockDto()
							{
								Id = iw.Id,
								Batch = i.Batch,
								Audittime = iw.Audittime,
								Creator = iw.Creator,
								InWarehouseNumber = i.InWarehouseNumber,
								LocationName = it.LocationName,
								Name = w.Name,
								ProductCode = p.ProductCode,
								ProductName = p.ProductName,
								Remarks = iw.Remarks,
								Reviewer = iw.Reviewer,
								State = iw.State,
								SupplierName = iw.SupplierName,
								UnitName = p.Unit,
								WarehousingCode = iw.WarehousingCode,
								WarehousingType = iw.WarehousingType,
							}).ToList();
				if (!string.IsNullOrEmpty(input.WarehousingCode))
				{
					list = list.Where(x => x.WarehousingCode.Contains(input.WarehousingCode)).ToList();
				}

				if (input.WarehousingType != 0 || input.WarehousingType == null)
				{
					list = list.Where(x => x.WarehousingType == input.WarehousingType).ToList();
				}

				if (input.State != 0)
				{
					list = list.Where(x => x.State == input.State).ToList();
				}
				//总数量
				int totalCount = list.Count();
				int pageCount = (int)Math.Ceiling(totalCount / (double)input.PageSize);
				var result = list.Skip((input.PageIndex - 1) * input.PageSize).Take(input.PageSize).ToList();
				//var response = result.MapTo<List<Carrier>>();
				return result != null ? Response<List<StockDto>>.Ok(result, totalCount, pageCount) : Response<List<StockDto>>.Fail("查询失败");
			}
			catch (Exception)
			{

				throw;
			}
		}

		/// <summary>
		/// 添加入库信息
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		/// <exception cref="NotImplementedException"></exception>
		public async Task<Response<bool>> PostStockAdd(StockAdd input)
		{
			try
			{

				var InWare = input.inWarehouseDetailAdds;
				//获取入库详细信息
				var list = InWare.Select(x => new InWarehouseDetailAdd
				{
					Batch = x.Batch,
					InWarehouseNumber = x.InWarehouseNumber,
					Price = x.Price,
					ProductCode = x.ProductCode,
					WarehousingCode = input.WarehousingCode,
				}).ToList();
				var ProList = await _product.GetAllListAsync();
				//foreach (var item in input.inWarehouseDetailAdds)
				//{
				//    var proinfo = ProList.Where(x => x.ProductCode == item.ProductCode).FirstOrDefault();
				//    proinfo.Inventory += item.InWarehouseNumber;
				//    await _product.UpdateAsync(proinfo);
				//}

				var tolist = input.MapTo<InWarehouse>();



				using (var tran = _smartWMSContext.Database.BeginTransaction())
				{
					try
					{
						var i = await _inWarehouse.InsertAsync(tolist);
						if (i > 0)
						{
							var j = await _inWarehouseDetail.InsertAsync(list.MapToList<InWarehouseDetail>());
							if (j > 0)
							{
								tran.Commit();
								return Response<bool>.Ok(true);
							}
							else
							{
								tran.Rollback();
								return Response<bool>.Fail("添加失败");
							}
						}
						else
						{
							tran.Rollback();
							return Response<bool>.Fail("添加失败");
						}
					}
					catch (Exception)
					{

						throw;
					}
				}

			}
			catch (Exception)
			{

				throw;
			}
		}

		/// <summary>
		/// 获取采购列表
		/// </summary>
		/// <returns></returns>
		/// <exception cref="NotImplementedException"></exception>
		public async Task<List<ProcureManagementCode>> GetProcureManagementList()
		{
			try
			{
				var list = await _procureManagement.GetAllListAsync();
				var ProList = new List<ProcureManagementCode>();
				var listinfo = new ProcureManagementCode();
				foreach (var item in list)
				{
					listinfo.ProcurementCode = item.ProcurementCode;
					ProList.Add(listinfo);
				}
				return ProList;
			}
			catch (Exception)
			{

				throw;
			}
		}

		/// <summary>
		/// 入库单详细
		/// </summary>
		/// <param name="Id"></param>
		/// <returns></returns>
		/// <exception cref="NotImplementedException"></exception>
		public async Task<InWarehouseListDto> GetInWarehouseList(KeyEntity Id)
		{
			try
			{
				var InWareList = await _inWarehouse.GetAllListAsync();
				var list = InWareList.Where(x => x.Id == Id.Id).FirstOrDefault();
				var result = list.MapTo<InWarehouseListDto>();
				return result;
			}
			catch (Exception)
			{

				throw;
			}
		}
		/// <summary>
		/// 获取产品列表
		/// </summary>
		/// <param name="Id"></param>
		/// <returns></returns>
		/// <exception cref="NotImplementedException"></exception>
		public async Task<List<ProductDtoInWar>> GetProductDtojwz(KeyEntity Id)
		{
			try
			{
				var InWareList = await _inWarehouse.GetAllListAsync();
				var list = InWareList.Where(x => x.Id == Id.Id).FirstOrDefault();
				var InWareDetailList = await _inWarehouseDetail.GetAllListAsync();
				var InWareDetai = InWareDetailList.Where(x => x.InWarehouseCode == list.WarehousingCode).FirstOrDefault();
				var Location = await _location.GetAllListAsync();
				var Product = await _product.GetAllListAsync();

				var listInfo = from i in InWareList
							   join iw in InWareDetailList
							   on i.WarehousingCode equals iw.InWarehouseCode
							   join p in Product
							   on iw.ProductCode equals p.ProductCode
							   join l in Location
							   on p.DefaultLocationId equals l.Id
							   select new ProductDtoInWar()
							   {
								   ProductCode = p.ProductCode,
								   ProductName = p.ProductName,
								   LocationName = l.LocationName,
								   InWarehouseNumber = iw.InWarehouseNumber,
								   Batch = iw.Batch,
								   Price = ((decimal)iw.Price),
								   SumPrice = iw.InWarehouseNumber * (int)iw.Price,
								   Specs = p.Specs,
							   };

				var result = listInfo.ToList();
				return result;
			}
			catch (Exception)
			{

				throw;
			}
		}

		/// <summary>
		/// 反填查询入仓信息
		/// </summary>
		/// <param name="Id"></param>
		/// <returns></returns>
		public async Task<StockAdd> GetBackFill(KeyEntity Id)
		{
			try
			{
				var list = await _inWarehouse.GetAllListAsync();
				var result = list.Where(x => x.Id == Id.Id).FirstOrDefault();
				var inWareDetailList = await _inWarehouseDetail.GetAllListAsync();
				var inWareDetail = inWareDetailList.Where(x => x.InWarehouseCode == result.WarehousingCode).FirstOrDefault();
				var resultInfo = from i in list
								 join iw in inWareDetailList
								 on i.WarehousingCode equals iw.InWarehouseCode
								 where i.Id == Id.Id
								 select new StockAdd()
								 {
									 Id = i.Id,
									 WarehousingCode = i.WarehousingCode,
									 WarehousingType = i.WarehousingType,
									 SupplierName = i.SupplierName,
									 Audittime = i.Audittime,
									 Creator = i.Creator,
									 Reviewer = i.Reviewer,
									 Remarks = i.Remarks,
									 Contract = i.Contract,
									 Phone = i.Phone,
									 CreateTime = i.Audittime,
									 Opinion = i.Opinion,
									 State = i.State,
									 SupplierCode = i.SupplierCode,
									 UnitOrderId = i.UnitOrderId
								 };
				var resultInfoList = resultInfo.FirstOrDefault();
				return resultInfoList;
			}
			catch (Exception)
			{

				throw;
			}
		}

		/// <summary>
		/// 反填入库详细
		/// </summary>
		/// <param name="Id"></param>
		/// <returns></returns>
		public async Task<List<InWarehouseDetailAdd>> GetinWareDetailListBackfill(KeyEntity Id)
		{
			try
			{
				var list = await _inWarehouse.GetAllListAsync();
				var proList = await _product.GetAllListAsync();
				var inWareDetailList = await _inWarehouseDetail.GetAllListAsync();
				var Inventory = await _inventory.GetAllListAsync();
				var inWareDetail = (from i in list
									join iw in inWareDetailList
									on i.WarehousingCode equals iw.InWarehouseCode
									join p in proList
									on iw.ProductCode equals p.ProductCode
									join inv in Inventory
									on iw.ProductCode equals inv.ProductCode
									where i.Id == Id.Id
									select new InWarehouseDetailAdd()
									{
										Id = iw.Id,
										Batch = iw.Batch,
										InWarehouseNumber = iw.InWarehouseNumber,
										Price = iw.Price.ToDouble(),
										ProductCode = iw.ProductCode,
										WarehousingCode = i.WarehousingCode,
										ProductName = p.ProductName,
										UnitName = inv.Unit,
									}).ToList();
				return inWareDetail.MapToList<InWarehouseDetailAdd>();
			}
			catch (Exception)
			{

				throw;
			}
		}

		/// <summary>
		/// 修改入库信息
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		/// <exception cref="NotImplementedException"></exception>
		public async Task<Response<bool>> PostInWareUpdate(StockAdd input)
		{
			try
			{
				var InWare = input.inWarehouseDetailAdds;
				//获取入库详细信息
				var list = InWare.Select(x => new InWarehouseDetailAdd
				{
					Id = x.Id,
					Batch = x.Batch,
					InWarehouseNumber = x.InWarehouseNumber,
					Price = x.Price,
					ProductCode = x.ProductCode,
					WarehousingCode = input.WarehousingCode,
				}).ToList();
				var tolist = input.MapTo<InWarehouse>();
				using (var tran = _smartWMSContext.Database.BeginTransaction())
				{
					try
					{
						var i = await _inWarehouse.UpdateAsync(tolist);
						if (i > 0)
						{
							var j = await _inWarehouseDetail.UpdateRangeAsync(list.MapToList<InWarehouseDetail>());
							if (j > 0)
							{
								tran.Commit();
								return Response<bool>.Ok(true);
							}
							else
							{
								tran.Rollback();
								return Response<bool>.Fail("修改失败");
							}
						}
						else
						{
							tran.Rollback();
							return Response<bool>.Fail("修改失败");
						}
					}
					catch (Exception)
					{

						throw;
					}
				}
			}
			catch (Exception)
			{

				throw;
			}
		}

		/// <summary>
		/// 删除入库信息
		/// </summary>
		/// <param name="Id"></param>
		/// <returns></returns>
		/// <exception cref="NotImplementedException"></exception>
		public async Task<Response<bool>> DeletInWare(KeyEntity Id)
		{
			try
			{
				var InWarehouseList = await _inWarehouse.GetAllListAsync();
				var InWarehouseDetailList = await _inWarehouseDetail.GetAllListAsync();
				var InWarehouse = InWarehouseList.Where(x => x.Id == Id.Id).FirstOrDefault();
				var InWarehouseDetail = InWarehouseDetailList.Where(x => x.InWarehouseCode == InWarehouse.WarehousingCode).ToList();
				using (var tran = _smartWMSContext.Database.BeginTransaction())
				{
					try
					{
						var i = await _inWarehouse.DeleteByIdAsync(InWarehouse);
						if (i > 0)
						{
							var j = await _inWarehouseDetail.DeleteAsync(InWarehouseDetail);
							if (j > 0)
							{
								tran.Commit();
								return Response<bool>.Ok(true);
							}
							else
							{
								tran.Rollback();
								return Response<bool>.Fail("删除失败");
							}
						}
						else
						{
							tran.Rollback();
							return Response<bool>.Fail("删除失败");
						}
					}
					catch (Exception)
					{

						throw;
					}
				}
			}
			catch (Exception)
			{

				throw;
			}
		}


		/// <summary>
		/// 批量删除入库信息
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task<Response<bool>> DeleteBatches(List<StockAdd> input)
		{
			try
			{
				var List = _inWarehouse.GetListQuery().Where(x => input.Select(x => x.WarehousingCode).Contains(x.WarehousingCode)).ToList();
				var wlist = _inWarehouseDetail.GetListQuery().Where(x => input.Select(x => x.WarehousingCode).Contains(x.InWarehouseCode)).ToList();
				if (List != null)
				{
					using (var tran = _smartWMSContext.Database.BeginTransaction())
					{
						try
						{
							var result = await _inWarehouse.DeleteAsync(List);
							if (result > 0)
							{
								var result1 = await _inWarehouseDetail.DeleteAsync(wlist);
								if (result1 > 0)
								{
									tran.Commit();
									return Response<bool>.Ok(true);
								}
								else
								{
									tran.Rollback();
									return Response<bool>.Fail("删除失败");
								}
							}
							else
							{
								tran.Rollback();
								return Response<bool>.Fail("删除失败");
							}
						}
						catch (Exception)
						{

							throw;
						}
					}

				}
				else
				{
					return Response<bool>.Fail("删除失败");
				}
			}
			catch (Exception)
			{

				throw;
			}
		}

		/// <summary>
		/// 修改入库审核状态
		/// </summary>
		/// <param name="Id"></param>
		/// <returns></returns>
		/// <exception cref="NotImplementedException"></exception>
		public async Task<Response<bool>> GetInWarehouseListState(InWarehouseSteatDto input)
		{
			try
			{
				var InWarehouseDetail = await _inWarehouseDetail.GetAllListAsync();
				var list = await _inWarehouse.GetAllListAsync();
				var result = list.Where(x => x.Id == input.Id).FirstOrDefault();
				result.State = input.State;
				var ProductList = await _product.GetAllListAsync();

				var infoList = (from w in list
								join iw in InWarehouseDetail
								on w.WarehousingCode equals iw.InWarehouseCode
								join p in ProductList
								on iw.ProductCode equals p.ProductCode
								where w.Id == input.Id
								select new Product()
								{
									Ceiling = p.Ceiling,
									DefaultCustomId = p.DefaultCustomId,
									DefaultLocationId = p.DefaultLocationId,
									DefaultSupplierId = p.DefaultSupplierId,
									DefaultWarehouseId = p.DefaultWarehouseId,
									Describe = p.Describe,
									FactoryNo = p.FactoryNo,
									Floor = p.Floor,
									Id = p.Id,
									InnerNo = p.InnerNo,
									Inventory = p.Inventory,
									PackageType = p.PackageType,
									Price = p.Price,
									ProductCode = p.ProductCode,
									ProductName = p.ProductName,
									ProductTypeId = p.ProductTypeId,
									Specs = p.Specs,
									Unit = p.Unit,
									Weight = p.Weight,
								}).FirstOrDefault();



				if (input.State == 1)
				{
					result.Opinion = input.Opinion;
					infoList.Inventory = infoList.Inventory + infoList.Inventory;
				}
				var i = await _inWarehouse.UpdateAsync(result);
				var j = await _product.UpdateAsync(infoList);
				if (i > 0)
				{
					return Response<bool>.Ok(true);
				}
				else
				{
					return Response<bool>.Fail("修改失败");
				}

			}
			catch (Exception)
			{

				throw;
			}
		}
	}
}
